#include <exception>
#ifdef _WIN32
#include <cppconn\exception.h>
#include <mysql_connection.h>
#else
#include <cppconn/exception.h>
#endif // _WIN32
#include <mysql_driver.h>
#include "MySqlConnector.h"
#ifdef _WIN32
#include <cppconn\statement.h>
#else
#include <cppconn/statement.h>
#endif
namespace MySql
{
	/******************************************************************
	************
	* ++
	* Method name 	: constructor
	* Description   : none
	* Parameters    : none
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : void
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	MySqlConnector::MySqlConnector()
	{
		mpConnection = nullptr; //
		mpDriver = sql::mysql::get_driver_instance();
	}

	/******************************************************************
	************
	* ++
	* Method name 	: connect
	* Description   : Open MySql Connector
	* Parameters    : host : Host to connect; userName: Username to login; password: Password to login
	*						   : port MySql port, default is 3306
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : true if connect success, false other wise, through exception if driver is not support
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	bool MySqlConnector::connect(std::string host, std::string userName, std::string password, unsigned int port)
	{
		// open connection
		auto url = "tcp://" + host + std::string(":") + std::to_string(port);
		try
		{
			if (mpConnection != nullptr)
			{
				delete mpConnection; // free resource
			}
			mpConnection = mpDriver->connect(url, userName, password);
		}
		catch (sql::SQLException &ex)
		{
			std::cout << ex.what();
		}

		return mpConnection != nullptr;
	}

	/******************************************************************
	************
	* ++
	* Method name 	: setSchema
	* Description   : set mysql schema for current database
	* Parameters    : schema: schema to set
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : void
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	void MySqlConnector::setSchema(std::string schema)
	{
		if (mpConnection == nullptr)
		{
			throw; // mpConnection not initialize
		}

		mpConnection->setSchema(schema);
	}

	/******************************************************************
	************
	* ++
	* Method name 	: exceQuery
	* Description   : exec query
	* Parameters    : query : sql command to exec
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : a pointer to result set (need to delete after unuse it)
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	sql::ResultSet* MySqlConnector::execQuery(std::string query)
	{
		std::auto_ptr<sql::Statement> statement = std::auto_ptr<sql::Statement>(mpConnection->createStatement());
		auto result = statement->executeQuery(sql::SQLString(query));

		return result;
	}

	/******************************************************************
	************
	* ++
	* Method name 	: excute
	* Description   : Exec a query of mysql
	* Parameters    : query: query of database
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : true if exec success, false otherwise
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	bool MySqlConnector::execute(std::string query)
	{
		std::auto_ptr<sql::Statement> statement = std::auto_ptr<sql::Statement>(mpConnection->createStatement());
		auto result = statement->execute(sql::SQLString(query));

		return result;
	}

	/******************************************************************
	************
	* ++
	* Method name 	: execUpdate
	* Description   : qexce query on update
	* Parameters    : query to exec
	*
	* Global Variables
	*    Accessed   : none
	*    Modified   : none
	*
	* Return values : number of result success
	*
	* Modifications  : Endless love
	* Description
	*
	* --
	*******************************************************************
	**********/
	int MySqlConnector::execUpdate(std::string query)
	{
		std::auto_ptr<sql::Statement> statement = std::auto_ptr<sql::Statement>(mpConnection->createStatement());
		auto result = statement->executeUpdate(sql::SQLString(query));

		return result;
	}

	// delete resource
	MySqlConnector::~MySqlConnector()
	{
		if (mpConnection != nullptr)
		{
			delete mpConnection; // delete connection
		}
	}
}
